<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://best.openssf.org/assets/css/style.css">
<link rel="stylesheet" href="checker.css">
<script src="checker.js"></script>
<script src="input1.js"></script>
<link rel="license" href="https://creativecommons.org/licenses/by/4.0/">

<!-- See create_labs.md for how to create your own lab! -->

</head>
<body>
<!-- For GitHub Pages formatting: -->
<div class="container-lg px-3 my-5 markdown-body">
<h1>Lab Exercise input1</h1>
<p>
This is a lab exercise on developing secure software.
For more information, see the <a href="introduction.html" target="_blank">introduction to
the labs</a>.

<p>
<h2>Goal</h2>
<p>
Practice validating input of a simple data type.

<p>
<h2>Background</h2>
<p>
In this exercise, we'll add some simple input validation to
a server-side program written in JavaScript using the
Express framework (version 4) and the express-validator library.
The point isn't to learn about these specific technologies;
the point is to learn how to write secure software in general.

<p>
<!-- https://expressjs.com/en/guide/routing.html -->
Express allows us to state that when the system receives a specific request,
it will run a list of functions ("handlers").
The library <tt>express-validator</tt> provides a set of validation functions
to make it easy to add validation checks.

<p>
The code below sets up handlers for a <tt>get</tt> request on path
<tt>/invoices</tt>.
If there are no validation errors, the code is supposed to show the invoice id.
If there is a validation error, it responds with HTTP
error code 422 ("Unprocessable Content"), a status code suggesting
that the request was invalid for some reason, along with an error message.

<p>
Unfortunately, this program doesn't <i>do</i> proper input validation.
In this application
<tt>id</tt> is supposed to <i>only</i> be an integer
between 1 and 9999 (including those numbers).
As written below it fails to make that check.
In fact, as written,
this program has a vulnerability we haven't discussed yet called
Cross-site Scripting (XSS).
Because of this XSS vulnerability,
an attacker could provide malicious scripts in <tt>id</tt> which the
viewer would automatically run!
This particular vulnerability would be entirely prevented if we did
better input validation.

<p>
<h2>Task Information</h2>
<p>
To complete this task:
<ol>
<li>After the first parameter to <tt>app.get</tt>
which says <tt>'/invoices'</tt>,
add a new comma-separated parameter.
<li>Start this new parameter with
<tt>query('id')</tt> to select the
<tt>id</tt> parameter for validation (we've filled in this part
to help get you started).
<li>After <tt>query('id')</tt> (and before the terminating comma),
add a period (<tt>.</tt>) and the validation requirement
<tt>isInt()</tt> (<tt>isInt</tt> validates that the named parameter is
an integer).
<li>The <tt>isInt</tt> method takes, as an optional parameter inside
its parentheses,
an object providing a minimum and maximum, e.g.,
<tt>isInt({min: YOUR_MINIMUM, max: YOUR_MAXIMUM})</tt>.
Set <tt>min</tt> and <tt>max</tt> to specify the allowed range.
</ol>

<p>
Note: JavaScript names are case-sensitive, so <tt>isint</tt> won't work.
Remember to indicate the end of this parameter with a comma
(our starter text does this).

<p>
Use the “hint” and “give up” buttons if necessary.

<p>
<h2>Interactive Lab (<span id="grade"></span>)</h2>
<p>
<b>The code below accepts the query parameter <tt>id</tt> as input.
Please change it so <tt>id</tt> is only accepted if it is
an integer between 1 and 9999 (including those numbers).</b>
<p>
<!--
You can use this an example for new labs.
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
<textarea id="attempt" rows="2" cols="65">...</textarea>
-->
<form id="lab">
<pre><code
>// Set up Express framework and express-validator library
const express = require("express");
const app = express();
const { query, matchedData, validationResult } =
    require('express-validator');

// Implement requests, e.g., http://localhost:3000/invoices?id=1
app.get('/invoices',
<input id="attempt0" type="text" size="65" spellcheck="false"
 value="  query('id'),">
  (req, res) =&gt; { // Execute this code if /invoices seen
    const result = validationResult(req); // Retrieve errors
    if (result.isEmpty()) { // No errors
      const data = matchedData(req); // Retrieve matching data
      return res.send(`You requested invoice id ${data.id}!`);
    }
    res.status(422).send(`Invalid input`);
  })
</code></pre>
<button type="button" class="hintButton">Hint</button>
<button type="button" class="resetButton">Reset</button>
<button type="button" class="giveUpButton">Give up</button>
<br><br>
<p>
<i>This lab was developed by David A. Wheeler at
<a href="https://www.linuxfoundation.org/"
>The Linux Foundation</a>.</i>
<br><br><!-- These go in the last form if there's more than one: -->
<p id="correctStamp" class="small">
<textarea id="debugData" class="displayNone" rows="20" cols="65" readonly>
</textarea>
</form>

</div><!-- End GitHub pages formatting -->
</body>
</html>
